﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;

namespace SerializationTest
{
    [Serializable]
    public class Student
    {
        public string StudentId { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Class { get; set; }

        public Student() { }

        public Student(string studentId, string name, int age, string className)
        {
            StudentId = studentId;
            Name = name;
            Age = age;
            Class = className;
        }

        public override string ToString()
        {
            return $"学号：{StudentId}，姓名：{Name}，年龄：{Age}，班级：{Class}";
        }
    }

    // JSON功能类
    public class JsonStudentManager
    {
        private string filePath;

        public JsonStudentManager(string path)
        {
            filePath = path;
        }

        // 1、使用json序列化学生集合，并保存在文件中
        public void SerializeStudents(List<Student> students)
        {
            try
            {
                FileStream fs = new FileStream(filePath, FileMode.Create);

                // 使用JsonSerializerOptions进行格式化输出
                var options = new JsonSerializerOptions
                {
                    WriteIndented = true, // 格式化输出，便于阅读
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 使用驼峰命名
                    PropertyNameCaseInsensitive = true  // 不要严格匹配属性名称的大小写
                };

                // 使用Utf8JsonWriter进行序列化
                Utf8JsonWriter jw = new Utf8JsonWriter(fs);
                JsonSerializer.Serialize(jw, students, options);

                fs.Close();
                Console.WriteLine($"学生数据已JSON序列化并保存到：{filePath}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"JSON序列化失败：{ex.Message}");
            }
        }

        // 2、使用反序列化技术，读取文件内容，并遍历显示
        public List<Student> DeserializeStudents()
        {
            try
            {
                if (!File.Exists(filePath))
                {
                    Console.WriteLine("JSON文件不存在！");
                    return new List<Student>();
                }

                FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);

                // 使用StreamReader读取文件内容
                StreamReader sr = new StreamReader(fs, System.Text.Encoding.UTF8);
                string jsonData = sr.ReadToEnd();

                // 配置反序列化选项
                var options = new JsonSerializerOptions
                {
                    // 必须与序列化时的命名策略一致
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                    // 启用属性名称不区分大小写
                    PropertyNameCaseInsensitive = true
                };

                // 使用泛型方法进行反序列化JSON数据
                List<Student> students = JsonSerializer.Deserialize<List<Student>>(jsonData, options);

                //List<Student> students = (List<Student>)JsonSerializer.Deserialize(jsonData, typeof(List<Student>));

                fs.Close();

                // 遍历显示所有学生
                Console.WriteLine("JSON反序列化成功！学生信息如下：");
                Console.WriteLine("=================================");
                foreach (var student in students)
                {
                    Console.WriteLine(student);
                }
                Console.WriteLine("=================================");

                return students;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"JSON反序列化失败：{ex.Message}");
                return new List<Student>();
            }
        }
    }

    // 测试类
    class Program
    {
        static void Main(string[] args)
        {
            string appPath = Environment.CurrentDirectory;
            string jsonFilePath = Path.Combine(appPath, "students.json");

            JsonStudentManager jsonManager = new JsonStudentManager(jsonFilePath);

            while (true)
            {
                Console.WriteLine("\n请选择功能：");
                Console.WriteLine("1. 创建测试学生数据并JSON序列化");
                Console.WriteLine("2. JSON文件反序列化并显示");
                Console.WriteLine("0. 退出");

                string choice = Console.ReadLine();

                if (choice == "0") break;

                switch (choice)
                {
                    case "1":
                        TestSerialization(jsonManager);
                        break;
                    case "2":
                        TestDeserialization(jsonManager);
                        break;
                    default:
                        Console.WriteLine("无效选择，请重新输入！");
                        break;
                }
            }
        }

        // 测试序列化功能
        private static void TestSerialization(JsonStudentManager jsonManager)
        {
            try
            {
                List<Student> students = CreateTestStudents();

                Console.WriteLine("创建的学生数据：");
                DisplayStudents(students);

                jsonManager.SerializeStudents(students);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"测试序列化时出错：{ex.Message}");
            }
        }

        // 测试反序列化功能
        private static void TestDeserialization(JsonStudentManager jsonManager)
        {
            try
            {
                List<Student> loadedStudents = jsonManager.DeserializeStudents();

                if (loadedStudents.Count > 0)
                {
                    Console.WriteLine($"成功加载 {loadedStudents.Count} 个学生数据");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"测试反序列化时出错：{ex.Message}");
            }
        }

        // 创建测试学生数据
        private static List<Student> CreateTestStudents()
        {
            return new List<Student>
            {
                new Student("1001", "张三", 20, "计算机1班"),
                new Student("1002", "李四", 21, "计算机2班"),
                new Student("1003", "王五", 19, "计算机1班"),
                new Student("1004", "赵六", 22, "软件工程1班"),
                new Student("1005", "钱七", 20, "软件工程2班")
            };
        }

        // 显示学生列表
        private static void DisplayStudents(List<Student> students)
        {
            Console.WriteLine("=================================");
            foreach (var student in students)
            {
                Console.WriteLine(student);
            }
            Console.WriteLine("=================================");
        }
    }
}
